<template>
  <div class="dropEl">
    <div v-if="jobMode == 'BATCH'">
      <el-divider
        content-position="left"
      ><h3>
        批量同步配置
        <el-switch v-model="data.batchStatus" name="batch" /></h3></el-divider>
      <div v-if="data.jdbc && data.batchStatus">
        <el-table
          border
          :data="data.jdbc"
          style="width: 90%; margin: 0 auto"
          :height="300"
        >
          <el-table-column prop="tableName" label="表名" />
          <el-table-column label="同步方式">
            <template slot-scope="scope">
              <el-select v-model="scope.row.syncType" placeholder="请选择类型">
                <el-option
                  v-for="item in dict.type.data_sync_batch_type"
                  :key="item.value"
                  :label="item.label"
                  :value="item.value"
                />
              </el-select>
            </template>
          </el-table-column>
          <el-table-column prop="sortBy" label="排序方式">
            <template slot-scope="scope">
              <el-select
                v-model="scope.row.sortBy"
                placeholder="请选择排序方式"
              >
                <el-option
                  v-for="item in scope.row.sortBySelectList"
                  :key="item"
                  :label="item"
                  :value="item"
                />
              </el-select>
            </template>
          </el-table-column>
          <el-table-column prop="slice" label="切片数">
            <template slot-scope="scope">
              <el-autocomplete
                v-model="scope.row.slice"
                class="inline-input"
                :fetch-suggestions="querySliceSearch"
                placeholder="请输入切片数"
              />
            </template>
          </el-table-column>

          <el-table-column prop="sliceSize" label="切片大小">
            <template slot-scope="scope">
              <el-autocomplete
                v-model="scope.row.sliceSize"
                class="inline-input"
                :fetch-suggestions="querySliceSizeSearch"
                placeholder="请输入切片大小"
              />
            </template>
          </el-table-column>

          <el-table-column prop="pageSize" label="分页大小">
            <template slot-scope="scope">
              <el-autocomplete
                v-model="scope.row.pageSize"
                class="inline-input"
                :fetch-suggestions="queryPageSizeSearch"
                placeholder="请输入分页大小"
              />
            </template>
          </el-table-column>

          <el-table-column prop="last" label="偏移" />
        </el-table>
      </div>
    </div>
    <div
      v-if="
        data.jobType[1] == 'SYNC_STRUCTURE' || data.jobType[1] == 'CREATE_TABLE'
      "
    >
      <TypeMapping :data="data" />
    </div>
    <div v-if="jobMode == 'STREAMING'">
      <Streaming :data="data" />
    </div>
    <div v-if="jobMode == 'BATCH' || jobMode == 'STREAMING'">
      <el-divider
        content-position="left"
      ><h3>
        映射关系配置
        <el-switch
          v-model="data.mappingStatus"
          name="batch"
          @change="(v) => handelcdcSwitchChange(v, 'batch')"
        /></h3></el-divider>
      <div
        v-if="data.mappingStatus && data.mapping"
        style="width: 90%; margin: 0 auto"
      >
        <div class="add-btn">
          <el-button
            size="medium"
            type="primary"
            @click="handleAddScript"
          >添 加</el-button>
        </div>
        <el-table
          :key="updateTable"
          border
          style="width: 100%; margin-top: 15px"
          :height="300"
          :data="data.mapping"
        >
          <el-table-column prop="tableName" label="表名" />
          <el-table-column prop="column" label="字段名" />
          <el-table-column prop="rule" label="读入名称">
            <template slot-scope="scope">
              <span>{{ scope.row.readRule.rule }}</span>
            </template>
          </el-table-column>
          <el-table-column label="读入类型">
            <template slot-scope="scope">
              <span>{{ scope.row.readRule.ruleType }}</span>
            </template>
          </el-table-column>
          <el-table-column label="读入脚本">
            <template slot-scope="scope">
              <el-button
                size="mini"
                type="text"
                :disabled="
                  scope.row.readRule.ruleType == 'DEFAULT' ||
                    scope.row.readRule.ruleContent.length == 0
                "
                @click="handleViewCode(scope.row, 'readRule')"
              >查看</el-button>
            </template>
          </el-table-column>
          <el-table-column prop="rule" label="写入名称">
            <template slot-scope="scope">
              <span>{{ scope.row.writeRule.rule }}</span>
            </template>
          </el-table-column>
          <el-table-column label="写入类型">
            <template slot-scope="scope">
              <span>{{ scope.row.writeRule.ruleType }}</span>
            </template>
          </el-table-column>
          <el-table-column label="写入脚本" prop="ruleContent">
            <template slot-scope="scope">
              <el-button
                size="mini"
                type="text"
                :disabled="
                  scope.row.writeRule.ruleType == 'DEFAULT' ||
                    scope.row.writeRule.ruleContent.length == 0
                "
                @click="handleViewCode(scope.row, 'writeRule')"
              >查看</el-button>
            </template>
          </el-table-column>
          <el-table-column label="操作">
            <template slot-scope="scope">
              <el-button
                size="mini"
                type="text"
                @click="handleEditRules(scope.row, scope.$index)"
              >编辑</el-button>
              <el-button
                size="mini"
                type="text"
                style="color: red"
                @click="handleRemoveRow(scope.row, scope.$index)"
              >删除</el-button>
            </template>
          </el-table-column>
        </el-table>
      </div>
    </div>
    <div>
      <monitorConf dicts="synchronous_tasktype" :data="data" job-id="6" />
    </div>

    <el-dialog
      title="字段映射规则"
      :visible.sync="dialogVisible"
      width="80%"
      :before-close="handleClose"
      append-to-body
    >
      <div class="script-box">
        <el-form
          ref="columnRules"
          :model="rulesForm"
          :rules="rules.columnRules"
          size="small"
          :inline="true"
          label-width="90px"
        >
          <el-form-item label="表名" prop="tableName">
            <el-select
              v-model="rulesForm.tableName"
              placeholder="请选择表名"
              @change="getColumnList"
            >
              <el-option
                v-for="item in data.jdbc"
                :key="item.tableName"
                :label="item.tableName"
                :value="item.tableName"
              />
            </el-select>
          </el-form-item>
          <el-form-item label="字段" prop="column">
            <el-select v-model="rulesForm.column" placeholder="请选择字段">
              <el-option
                v-for="item in cureentSelect"
                :key="item"
                :label="item"
                :value="item"
              />
            </el-select>
          </el-form-item>
        </el-form>
        <el-divider
          content-position="left"
        ><span class="dicider-title">源库-读入方式</span></el-divider>
        <el-form
          ref="readRuleRules"
          :model="rulesForm.readRule"
          :rules="rules.readRuleRules"
          size="small"
          :inline="true"
          label-width="90px"
        >
          <el-form-item label="规则类型" prop="ruleType">
            <el-select
              v-model="rulesForm.readRule.ruleType"
              placeholder="请选择规则类型"
            >
              <el-option
                v-for="item in dict.type.data_sync_column_ruletype"
                :key="item.value"
                :label="item.label"
                :value="item.value"
              />
            </el-select>
          </el-form-item>
          <el-form-item label="规则脚本" prop="ruleContent">
            <el-button
              :disabled="rulesForm.readRule.ruleType == 'DEFAULT'"
              size="mini"
              type="primary"
              @click="handleEditCode('readRule')"
            >编辑规则脚本</el-button>
          </el-form-item>
          <el-form-item label="读入规则备注" label-width="120px">
            <el-input
              v-model="rulesForm.readRule.rule"
              placeholder="请填写读入规则备注"
            />
          </el-form-item>
        </el-form>
        <el-divider
          content-position="left"
        ><span class="dicider-title">目标库-写入方式</span></el-divider>
        <el-form
          ref="writeRuleRules"
          :model="rulesForm.writeRule"
          :rules="rules.writeRuleRules"
          size="small"
          :inline="true"
          label-width="90px"
        >
          <el-form-item label="规则类型" prop="ruleType">
            <el-select
              v-model="rulesForm.writeRule.ruleType"
              placeholder="请选择规则类型"
            >
              <el-option
                v-for="item in dict.type.data_sync_column_ruletype"
                :key="item.value"
                :label="item.label"
                :value="item.value"
              />
            </el-select>
          </el-form-item>
          <el-form-item label="规则脚本" prop="ruleContent">
            <el-button
              :disabled="rulesForm.writeRule.ruleType == 'DEFAULT'"
              size="mini"
              type="primary"
              @click="handleEditCode('writeRule')"
            >编辑规则脚本</el-button>
          </el-form-item>
          <el-form-item label="写入规则备注" label-width="120px">
            <el-input
              v-model="rulesForm.readRule.rule"
              placeholder="请填写写入规则备注"
            />
          </el-form-item>
        </el-form>
      </div>
      <span slot="footer" class="dialog-footer">
        <el-button @click="dialogVisible = false">取 消</el-button>
        <el-button type="primary" @click="addFieldMap">确 定</el-button>
      </span>
    </el-dialog>

    <el-dialog
      :key="updateTable"
      title="groovy脚本"
      :visible.sync="dialogGroovyCodeVisible"
      width="80%"
    >
      <codeEditor
        ref="codeEditor"
        :key="updateTable"
        :editor-hight="500"
        :code-data="groovyCode"
        value-code-lang="groovy"
        :read-only="readOnly"
      />
      <span slot="footer" class="dialog-footer">
        <el-button @click="dialogGroovyCodeVisible = false">取 消</el-button>
        <el-button type="primary" @click="handleEditCodeEnter">确 定</el-button>
      </span>
    </el-dialog>
  </div>
</template>
<script>
import Streaming from './stepsFourComponents/streaming.vue'
import codeEditor from '@/components/CodeEditor/index.vue'

import monitorConf from '@/views/components/monitorConf/index.vue'

import { databaseListDbColumns } from '@/api/console/datasourceInfo'
import TypeMapping from './stepsFourComponents/typeMapping.vue'
import Vue from 'vue'

export default {
  dicts: [
    'appraise_taskmode',
    'conf_sync_dict',
    'sys_job_status',
    'data_sync_batch_type',
    'data_sync_column_ruletype',
    'synchronous_batch_slice',
    'synchronous_batch_slicesize',
    'synchronous_batch_pagesize'
  ],
  components: { codeEditor, Streaming, monitorConf, TypeMapping },
  props: ['data'],
  data() {
    return {
      readOnly: false,
      codekeyWord: '',
      groovyCode: '',
      dialogGroovyCodeVisible: false,
      cureentSelect: [],
      rulesForm: {},
      scriptIndex: 0,
      dialogVisible: false,
      open: false,
      cdcTemplateList: [],
      randomForm: null,
      dictOptions: [],
      jobTemplateList: [],
      jobMode: '',
      editIndex: null,
      updateTable: null,
      rules: {
        columnRules: {
          column: [{ required: true, message: '请选择字段', trigger: 'blur' }],
          tableName: [
            { required: true, message: '请选择表名', trigger: 'blur' }
          ]
        },
        readRuleRules: {
          rule: [
            { required: true, message: '请选择规则模板', trigger: 'blur' }
          ],
          ruleType: [
            { required: true, message: '请选择规则类型', trigger: 'blur' }
          ]
        },
        writeRuleRules: {
          rule: [
            { required: true, message: '请选择规则模板', trigger: 'blur' }
          ],
          ruleType: [
            { required: true, message: '请选择规则类型', trigger: 'blur' }
          ]
        }
      },
      sliceRestaurants: [],
      sliceSizeRestaurants: [],
      pageSizeRestaurants: [],
      openCron: false,
      expression: ''
    }
  },
  async created() {
    const that = this
    const { batchStatus, batchConf, mapping, jdbc, mappingStatus } =
      this.$props.data
    this.jobMode = this.$props.data.jobMode
    this.reset()
    if (batchStatus === undefined) {
      Vue.set(this.$props.data, 'batchStatus', false)
    }
    if (mappingStatus === undefined) {
      Vue.set(this.$props.data, 'mappingStatus', false)
    }
    if (mapping === undefined) {
      Vue.set(this.$props.data, 'mapping', [])
    }
    if (!batchConf) {
      Vue.set(this.$props.data, 'batchConf', [])
    }
    if (!jdbc) {
      Vue.set(this.$props.data, 'jdbc', [])
    }

    if (jdbc && jdbc.length > 0) {
      const arr = []
      const tableNames = []
      jdbc.forEach((f) => {
        tableNames.push(f.name || f.tableName)
        arr.push({
          tableName: f.name,
          syncType: 'FULL_SYNC',
          last: null,
          sortBy: f.sortBy || null,
          sortBySelectList: [],
          ...f
        })
      })
      const { data } = await databaseListDbColumns({
        databaseName: this.$props.data.sourceDatabase,
        id: this.$props.data.sourceId,
        tableNames
      })
      Object.keys(data.data).forEach((f) => {
        const findItem = arr.find((j) => j.tableName === f)
        if (!findItem.sortBy) {
          findItem.sortBy = data.data[f][0]
        }
        findItem.pageSize =
          findItem.pageSize ||
          this.dict.type.synchronous_batch_pagesize[0].value
        findItem.slice =
          findItem.slice || this.dict.type.synchronous_batch_slice[0].value
        findItem.sliceSize =
          findItem.sliceSize ||
          this.dict.type.synchronous_batch_slicesize[0].value
        findItem.sortBySelectList = data.data[f]
      })
      this.$props.data.jdbc = arr
    }
  },
  async mounted() {
    this.getDicts('synchronous_batch_slice').then((res) => {
      res.data.forEach((f) => {
        this.sliceRestaurants.push({
          value: f.dictValue
        })
      })
    })

    this.getDicts('synchronous_batch_slicesize').then((res) => {
      res.data.forEach((f) => {
        this.sliceSizeRestaurants.push({
          value: f.dictValue
        })
      })
    })

    this.getDicts('synchronous_batch_pagesize').then((res) => {
      res.data.forEach((f) => {
        this.pageSizeRestaurants.push({
          value: f.dictValue
        })
      })
    })
    return false
  },
  methods: {
    handelcdcSwitchChange(v, name) {
      if (!v) {
        this.$props.data[`${name}Conf`] = {}
      }
    },
    addFieldMap() {
      if (this.editIndex != null) {
        this.$props.data.mapping[this.editIndex] = this.rulesForm
      } else {
        this.$props.data.mapping.push(this.rulesForm)
      }
      this.updateTable = Math.random()
      this.editIndex = null
      this.reset()
      this.dialogVisible = false
    },
    queryPageSizeSearch(queryString, cb) {
      var pageSizeRestaurants = this.pageSizeRestaurants

      var results = queryString
        ? pageSizeRestaurants.filter(
          this.createFilter(pageSizeRestaurants, queryString)
        )
        : pageSizeRestaurants
      // 调用 callback 返回建议列表的数据
      cb(results)
    },
    querySliceSizeSearch(queryString, cb) {
      var sliceSizeRestaurants = this.sliceSizeRestaurants

      var results = queryString
        ? sliceSizeRestaurants.filter(
          this.createFilter(sliceSizeRestaurants, queryString)
        )
        : sliceSizeRestaurants
      // 调用 callback 返回建议列表的数据
      cb(results)
    },
    querySliceSearch(queryString, cb) {
      var sliceRestaurants = this.sliceRestaurants
      var results = queryString
        ? sliceRestaurants.filter(
          this.createFilter(sliceRestaurants, queryString)
        )
        : sliceRestaurants
      // 调用 callback 返回建议列表的数据
      cb(results)
    },
    createFilter(data, queryString) {
      return (data) => {
        return (
          data.value.toLowerCase().indexOf(queryString.toLowerCase()) === 0
        )
      }
    },
    handleViewCode(row, type) {
      this.readOnly = true
      this.dialogGroovyCodeVisible = true
      this.groovyCode = row[type].ruleContent
      this.updateTable = Math.random()
    },
    handleEditCodeEnter() {
      this.rulesForm[this.codekeyWord].ruleContent =
        this.$refs.codeEditor.$refs.aceEditor.editor.getValue()
      this.dialogGroovyCodeVisible = false
    },
    handleEditCode(value) {
      this.dialogGroovyCodeVisible = true
      this.codekeyWord = value
      this.readOnly = false
      this.groovyCode =
        this.rulesForm[value].ruleContent.length == 0
          ? ''
          : this.rulesForm[value].ruleContent
      this.updateTable = Math.random()
    },
    reset() {
      this.rulesForm = {
        column: '',
        readRule: {
          rule: '',
          ruleType: 'SCRIPT_GROOVY',
          ruleContent: ''
        },
        writeRule: {
          rule: '',
          ruleType: 'SCRIPT_GROOVY',
          ruleContent: ''
        }
      }
    },
    handleEditRules(row, index) {
      this.rulesForm = JSON.parse(JSON.stringify(row))
      this.editIndex = index
      this.dialogVisible = true
    },
    handleRemoveRow(row, index) {
      const that = this
      this.$modal
        .confirm('是否确认删除当前数据项？')
        .then(function() {
          that.$props.data.mapping.splice(index, 1)
          // that.$props.data.mapping[index].splice(index, 1);
        })
        .then(() => {
          that.updateTable = Math.random()
          that.$modal.msgSuccess('删除成功')
        })
        .catch((err) => {})
    },
    handleAddScript() {
      this.dialogVisible = true
    },
    handleClose() {
      this.dialogVisible = false
      this.editIndex = null
      this.reset()
    },
    getColumnList(v) {
      const item = this.$props.data.jdbc.find((f) => f.tableName == v)
      this.cureentSelect = item.sortBySelectList
    }
  }
}
</script>

<style lang="scss" scoped>
.dropEl {
  width: 100%;
  margin: 30px auto;
  border: 1px solid #dcdfe6;
  padding: 20px;

  h3 {
    font-weight: 600;
  }

  p {
    vertical-align: middle;
    font-size: 14px;
    color: #606266;
    margin: 0;
    font-weight: 600;

    button {
      margin-left: 15px;
    }
  }

  p:before {
    content: "*";
    color: #ff4949;
    margin-right: 4px;
  }
}

::v-deep .el-divider--horizontal {
  margin: 25px 0 35px 0;
}

.dicider-title {
  font-size: 16px;
  color: #606266;
  font-weight: 600;
}

.script-box {
  border: 1px solid #ddd;
  padding: 15px 0px;

  .add-btn {
    margin: 10px 20px 0 20px;
    button {
      width: 110px;
    }
  }
}
</style>
